#pragma once

#include "DataStructs.h"
#include <D3DX10Mesh.h>

#define ERROR_RESOURCE_VALUE 1

template<typename TYPE> BOOL IsErrorResource( TYPE data )
{
    if( ( TYPE )ERROR_RESOURCE_VALUE == data )
        return TRUE;
    return FALSE;
}

class Mesh
{
public:
    Mesh();
    ~Mesh();

    HRESULT load(ID3D11Device* pd3dDevice, const WCHAR* strFilename);
	void	loadTextures(ID3D11DeviceContext* pContext);
	void    destroy();

    Material* getMaterial( UINT iMaterial ) { return _materials.at( iMaterial ); }
	const Subset& getSubset(UINT iSubset) const { return _subsets.at(iSubset); }

    UINT getSubsetsCount() const { return _subsets.size(); }
	UINT getMaterialsCount() const { return _materials.size(); }

	ID3D11Buffer* getIndexBuffer() {return _pIndexBuffer;};
	ID3D11Buffer* getVertextBuffer() {return _pVertexBuffer;};

	const BBOX& getBoundingBox() const {return _box;}

private:

	struct CacheEntry
	{
		UINT index;
		CacheEntry* pNext;
	};

    HRESULT loadGeometryFromOBJ( const WCHAR* strFilename );
    HRESULT loadMaterialsFromMTL( const WCHAR* strFileName );
    void    initMaterial( Material* pMaterial );

    DWORD   addVertex( UINT hash, VERTEX* pVertex );
    void    deleteCache();

	void optimizeMesh();
	HRESULT commitToDevice();

    std::vector<CacheEntry*> _vertexCache;   // Hashtable cache for locating duplicate vertices
	Vertexes _vertices;      // Filled and copied to the vertex buffer
    Indexes _indices;       // Filled and copied to the index buffer
    Attributes _attributes;    // Filled and copied to the attribute buffer

	Materials _materials;
	FacesSubsets _subsets;
	ID3D11Buffer* _pIndexBuffer;
	ID3D11Buffer* _pVertexBuffer;

	BBOX _box;

    WCHAR   _mediaDir[ MAX_PATH ];               // Directory where the mesh was found

	ID3D11Device* _pd3dDevice;
};